package com.ruoyi.task;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.domain.AdvIncome;
import com.ruoyi.domain.AdvIncomedetail;
import com.ruoyi.domain.AdvMembers;
import com.ruoyi.domain.AdvOrders;
import com.ruoyi.domain.Vo.AdvIncomeVo;
import com.ruoyi.mapper.AdvIncomeMapper;
import com.ruoyi.mapper.AdvIncomedetailMapper;
import com.ruoyi.mapper.AdvMembersMapper;
import com.ruoyi.mapper.AdvOrdersMapper;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.*;

@Slf4j
@Component
public class OrderTask {
    @Autowired
    @Resource
    private AdvIncomeMapper advIncomeMapper;
    @Autowired
    @Resource
    private AdvOrdersMapper advOrdersMapper;
    @Autowired
    @Resource
    private AdvIncomedetailMapper advIncomedetailMapper;
    @Autowired
    @Resource
    private AdvMembersMapper advMembersMapper;
    @Autowired
    @Resource
    private SysConfigMapper sysConfigMapper;

    public void testTask() {
        System.out.println("测试任务被执行了...");
    }

    /**
     * 订单结算定时器
     * 执行时间: 每天5点
     */
//    @Scheduled(cron = "0/3 * * * * ?")
//    @Scheduled(cron = "0 0 5 * * ?")
    @Transactional
    public void SettlementTask() {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 1. 计算结算的截止时间
        Date currentDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DAY_OF_YEAR, 7);
        currentDate = calendar.getTime();

        SysConfig sysConfig = new SysConfig();
        sysConfig.setConfigKey("sys_orders_days");
        SysConfig sysConfigResult = sysConfigMapper.selectConfig(sysConfig);
        String delayDay = sysConfigResult.getConfigValue();

        AdvIncomeVo advIncomeVo = new AdvIncomeVo();
        advIncomeVo.setCurrentDate(simpleDateFormat.format(currentDate));
        advIncomeVo.setDelayDay(delayDay);
        // 2. 获取所有结算日期超过7天的未结算订单结算订单
        final List<AdvOrders> ordersByTime = advOrdersMapper.findOrderByTime(advIncomeVo);
        if (ordersByTime.size() == 0) {
            log.info("---------- 没有未结算的订单 ----------");
            return;
        }
        // 3. 遍历结果, 把每一个会员的 总收益计算出, 放在map中, 订单id放在一个 list 中
        Map<Long, Double> incomes = new HashMap<>(); // key 是会员id  value 是总金额
        Map<Long, List<Long>> orderIds = new HashMap<>(); // key 是会员id  value 是订单id集合
        for (AdvOrders advOrders : ordersByTime) {
            final Long advMembersId = advOrders.getAdvMembersId();
            final Double income = incomes.get(advMembersId);
            // 3.1 根据 advMembersId 查询到会员信息
            AdvMembers advMembers = advMembersMapper.selectAdvMembersByAdvMembersId(advMembersId);
            Double taxRate = advMembers.getPayRate() / 100.0;
            advIncomeVo.setTaxRate(Long.valueOf(advMembers.getPayRate()));
            if (income == null) {
                // 如果没有值就添加一个新键值对
//                incomes.put(advMembersId, advOrders.getOrdersamount()*taxRate);
                incomes.put(advMembersId, 0.0); // 不计算自己的购买, 设置为0.0
                ArrayList<Long> list = new ArrayList<>();
                list.add(advOrders.getAdvOrdersId());
                orderIds.put(advMembersId, list);
            } else {
                // 如果有值就更新值
//                incomes.put(advMembersId, income + advOrders.getOrdersamount()*taxRate);
                incomes.put(advMembersId, 0.0);// 不计算自己的购买, 设置为0.0
                List<Long> orders = orderIds.get(advMembersId);
                orders.add(advOrders.getAdvOrdersId());
                orderIds.put(advMembersId, orders);
            }
        }
        // 4. 把对应的信息设置到 advIncome 中, 插入会员结算收益表中  key 是会员id  value 是总金额
        List<AdvIncome> incomeList = new ArrayList<AdvIncome>(); // 用于保存每一条advIncome
        Set<Long> incomesKeySet = incomes.keySet();
        for (Long incomesKey : incomesKeySet) {
            // 在插入之前判断是否是营销会员
            AdvMembers advMembers = advMembersMapper.selectAdvMembersByAdvMembersId(incomesKey);
            if(!advMembers.getIsSaler().equals('1')) {
                continue; // 不是营销会员就跳过
            }
            AdvIncome advIncome = new AdvIncome(
                    0L,
                    advIncomeVo.getCalDate(),
                    advIncomeVo.getCalMode(),
                    advIncomeVo.getTaxRate(),
                    incomes.get(incomesKey) + "",
                    "0",
                    0.0,
                    "0",
                    incomesKey + "",
                    advIncomeVo.getCalYear(),
                    advIncomeVo.getCalMonth(),
                    "0",
                    ""
            );
            incomeList.add(advIncome);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 5. 遍历income集合
        System.out.println("incomeList.size()--->"+incomeList.size());
        for (int i = 0; i < incomeList.size(); i++) {
            AdvIncome advIncome = incomeList.get(i);
            // 在插入之前判断是否是营销会员
            AdvMembers advMembers = advMembersMapper.selectAdvMembersByAdvMembersId(Long.valueOf(advIncome.getAdvMembersId()));
            if(!advMembers.getIsSaler().equals('1')) {
                continue; // 不是营销会员就跳过
            }
            advIncomeMapper.insertAdvIncome(advIncome);
            // 5.1 根据advIncome的id查询到下级的id
            List<Long> nextIds = advMembersMapper.getNextIds(Long.valueOf(advIncome.getAdvMembersId()));
            System.out.println("nextIds.size()----->"+nextIds.size());
            for (Long nextId : nextIds) {
                System.out.println("下级ID-------------->"+nextId);
            }
            // 5.2 遍历从i之后的advincome, 查看是否存在下级id
            for (int j = 0; j < incomes.size(); j++) {
                System.out.println("Long.valueOf(incomeList.get(j).getAdvMembersId())"+Long.valueOf(incomeList.get(j).getAdvMembersId()));

                if (nextIds.contains(Long.valueOf(incomeList.get(j).getAdvMembersId()))) {
                    System.out.println("--------->"+advIncome.getTotalAmountSub()+"<--------->"+incomeList.get(j).getTotalAmount());
                    Double faAmount = Double.valueOf(advIncome.getTotalAmountSub());
                    Double sonAmount = Double.valueOf(incomeList.get(j).getTotalAmount());
                    Double sonTaxRate = Double.valueOf(incomeList.get(j).getTaxRate() / 100.0);
                    System.out.println("下级会员的钱: " + sonAmount);
                    System.out.println("上级会员的钱: " + faAmount);
                    System.out.println("下级会员的比例: " + sonTaxRate);
                    advIncome.setTotalAmountSub((faAmount + sonAmount + "")); // (faAmount + (sonAmount * sonTaxRate)) + ""
                }
            }
            advIncome.setPayAmount((Double.valueOf(advIncome.getTotalAmount())
                    + Double.valueOf(advIncome.getTotalAmountSub())));
            // 5.3 遍历之后, 把当前advIncome设置进入数据库
            advIncomeMapper.updateAdvIncome(advIncome);
            // 5.4 根据[会员订单id][结算收益id]插入数据到[会员结算收益明细表]
            List<Long> orderIdList = orderIds.get(Long.valueOf(advIncome.getAdvMembersId()));
            for (Long orderId : orderIdList) {
                advIncomedetailMapper.insertAdvIncomedetail(new AdvIncomedetail(
                        UUIDUtils.timeMillisId(),
                        advIncome.getAdvIncomeId(),
                        orderId
                ));
                // 5.4.1 设置结算过的订单的是否结算字段为 1[已结算]
                advOrdersMapper.updateBalFlag(orderId);
            }
        }

    }

}
